import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import type { APIResponse, APIError } from '@/types';

// 扩展 Axios 配置类型
declare module 'axios' {
  interface InternalAxiosRequestConfig {
    metadata?: {
      startTime: number;
    };
    skipAuth?: boolean;
  }
}

// 请求配置接口
export interface RequestConfig extends AxiosRequestConfig {
  skipAuth?: boolean;
  skipErrorHandler?: boolean;
}

// 基础 API 客户端类
export class BaseAPI {
  protected client: AxiosInstance;
  private requestQueue = new Map<string, Promise<any>>();

  constructor(baseURL?: string, timeout = 10000) {
    this.client = axios.create({
      baseURL: baseURL || import.meta.env.VITE_API_URL || 'http://localhost:3001',
      timeout,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    this.setupInterceptors();
  }

  /**
   * 设置请求和响应拦截器
   */
  private setupInterceptors() {
    // 请求拦截器
    this.client.interceptors.request.use(
      (config) => {
        // 添加请求时间戳
        config.metadata = { startTime: Date.now() };

        // 添加认证头
        const token = this.getAuthToken();
        if (token && !config.skipAuth) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 添加请求 ID
        config.headers['X-Request-ID'] = this.generateRequestId();

        // 开发模式下打印请求信息
        if (import.meta.env.DEV) {
          console.log(`🚀 API Request: ${config.method?.toUpperCase()} ${config.url}`, {
            params: config.params,
            data: config.data,
          });
        }

        return config;
      },
      (error) => {
        console.error('❌ Request Error:', error);
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.client.interceptors.response.use(
      (response: AxiosResponse) => {
        // 计算请求耗时
        const duration = Date.now() - (response.config.metadata?.startTime || Date.now());

        // 开发模式下打印响应信息
        if (import.meta.env.DEV) {
          console.log(`✅ API Response: ${response.config.method?.toUpperCase()} ${response.config.url}`, {
            status: response.status,
            duration: `${duration}ms`,
            data: response.data,
          });
        }

        return response;
      },
      (error) => {
        // 处理响应错误
        return this.handleResponseError(error);
      }
    );
  }

  /**
   * 处理响应错误
   */
  private handleResponseError(error: any) {
    const { response, request, config } = error;

    let apiError: APIError;

    if (response) {
      // 服务器返回错误响应
      apiError = {
        code: response.data?.code || `HTTP_${response.status}`,
        message: response.data?.message || response.statusText || '请求失败',
        details: response.data?.details,
        timestamp: Date.now(),
      };

      // 特殊状态码处理
      switch (response.status) {
        case 401:
          this.handleUnauthorized();
          break;
        case 403:
          apiError.message = '没有权限访问该资源';
          break;
        case 404:
          apiError.message = '请求的资源不存在';
          break;
        case 429:
          apiError.message = '请求过于频繁，请稍后再试';
          break;
        case 500:
          apiError.message = '服务器内部错误';
          break;
        case 502:
        case 503:
        case 504:
          apiError.message = '服务暂时不可用，请稍后再试';
          break;
      }
    } else if (request) {
      // 网络错误
      apiError = {
        code: 'NETWORK_ERROR',
        message: '网络连接失败，请检查网络设置',
        timestamp: Date.now(),
      };
    } else {
      // 其他错误
      apiError = {
        code: 'UNKNOWN_ERROR',
        message: error.message || '未知错误',
        timestamp: Date.now(),
      };
    }

    // 开发模式下打印错误信息
    if (import.meta.env.DEV) {
      console.error(`❌ API Error: ${config?.method?.toUpperCase()} ${config?.url}`, apiError);
    }

    // 如果配置了跳过错误处理，直接抛出原始错误
    if (config?.skipErrorHandler) {
      return Promise.reject(error);
    }

    return Promise.reject(apiError);
  }

  /**
   * 处理未授权错误
   */
  private handleUnauthorized() {
    // 清除认证信息
    this.clearAuthToken();
    
    // 重定向到登录页面或触发登录流程
    if (typeof window !== 'undefined') {
      window.dispatchEvent(new CustomEvent('auth:unauthorized'));
    }
  }

  /**
   * 获取认证令牌
   */
  private getAuthToken(): string | null {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem('auth_token');
  }

  /**
   * 清除认证令牌
   */
  private clearAuthToken() {
    if (typeof window === 'undefined') return;
    localStorage.removeItem('auth_token');
  }

  /**
   * 生成请求 ID
   */
  private generateRequestId(): string {
    return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
  }

  /**
   * 通用请求方法
   */
  protected async request<T>(config: RequestConfig): Promise<APIResponse<T>> {
    try {
      const response = await this.client.request<APIResponse<T>>(config);
      return response.data;
    } catch (error) {
      throw error;
    }
  }

  /**
   * GET 请求
   */
  protected async get<T>(url: string, params?: any, config?: RequestConfig): Promise<APIResponse<T>> {
    return this.request<T>({
      method: 'GET',
      url,
      params,
      ...config,
    });
  }

  /**
   * POST 请求
   */
  protected async post<T>(url: string, data?: any, config?: RequestConfig): Promise<APIResponse<T>> {
    return this.request<T>({
      method: 'POST',
      url,
      data,
      ...config,
    });
  }

  /**
   * PUT 请求
   */
  protected async put<T>(url: string, data?: any, config?: RequestConfig): Promise<APIResponse<T>> {
    return this.request<T>({
      method: 'PUT',
      url,
      data,
      ...config,
    });
  }

  /**
   * DELETE 请求
   */
  protected async delete<T>(url: string, config?: RequestConfig): Promise<APIResponse<T>> {
    return this.request<T>({
      method: 'DELETE',
      url,
      ...config,
    });
  }

  /**
   * 防重复请求
   */
  protected async requestWithDeduplication<T>(
    key: string,
    requestFn: () => Promise<APIResponse<T>>
  ): Promise<APIResponse<T>> {
    // 如果已有相同请求在进行中，返回该请求的 Promise
    if (this.requestQueue.has(key)) {
      return this.requestQueue.get(key);
    }

    // 创建新请求
    const request = requestFn().finally(() => {
      // 请求完成后从队列中移除
      this.requestQueue.delete(key);
    });

    // 将请求添加到队列
    this.requestQueue.set(key, request);

    return request;
  }

  /**
   * 批量请求
   */
  protected async batchRequest<T>(requests: Array<() => Promise<APIResponse<T>>>): Promise<APIResponse<T>[]> {
    try {
      const results = await Promise.allSettled(requests.map(req => req()));
      
      return results.map((result, index) => {
        if (result.status === 'fulfilled') {
          return result.value;
        } else {
          console.error(`Batch request ${index} failed:`, result.reason);
          return {
            success: false,
            data: null as any,
            message: result.reason?.message || '请求失败',
            code: result.reason?.code || 'BATCH_REQUEST_ERROR',
          };
        }
      });
    } catch (error) {
      throw error;
    }
  }

  /**
   * 取消所有进行中的请求
   */
  public cancelAllRequests() {
    this.requestQueue.clear();
  }
}

// 创建默认 API 实例
export const apiClient = new BaseAPI();
